package com.chinasoft.maysham.manager.service.component;

import com.chinasoft.maysham.manager.container.DockerContainerHook;
import com.chinasoft.maysham.manager.exception.BizException;
import com.chinasoft.maysham.manager.model.Component;
import com.chinasoft.maysham.manager.model.ComponentInstance;
import com.chinasoft.maysham.manager.model.ComponentStatusEnum;
import com.chinasoft.maysham.manager.model.DockerComponentInfo;
import com.chinasoft.maysham.manager.repo.ComponentInstanceRepo;
import com.chinasoft.maysham.manager.repo.ComponentRepo;
import com.chinasoft.maysham.manager.response.ComponentStatus;
import com.chinasoft.maysham.manager.response.PageResult;
import com.chinasoft.maysham.manager.util.AuthUtil;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;

@Service
public class ComponentServiceImpl implements ComponentService {
    @Resource
    private ComponentRepo componentRepo;

    @Resource
    private ComponentInstanceRepo componentInstanceRepo;

    @Resource
    private DockerContainerHook dockerContainerHook;

    @Override
    public PageResult<Component> findPage(String projectId, String keyword, Pageable pageable) {
        Criteria criteria = Criteria.where("deleted").is(false).and("projectId").is(projectId);
        if (!StringUtils.isEmpty(keyword)) {
            criteria.and("name").regex(keyword,"i");
        }
        return componentRepo.findPage(criteria, pageable, Component.class);
    }

    @Override
    public Component create(String projectId, Component request) {
        boolean exist = componentRepo.exist(Criteria.where("deleted").is(false).and("name").is(request.getName()), Component.class);
        if (exist) {
            throw new BizException("duplicate name error");
        }
        Component component = new Component();
        component.setName(request.getName());
        component.setProjectId(projectId);
        DockerComponentInfo info = new DockerComponentInfo();
        info.setStatus(ComponentStatusEnum.CREATED);
        return componentRepo.save(component);
    }

    @Override
    public Component delete(String projectId, String componentId) {
        if (!componentRepo.deleteById(componentId, Component.class)){
            throw new BizException("delete failed");
        }
        return componentRepo.findById(componentId,Component.class);
    }

    @Override
    public Component update(String projectId, Component request) {
        Component component = componentRepo.findById(request.getId(), Component.class);
        if (component == null || !projectId.equals(component.getProjectId())){
            throw new BizException("invalid param");
        }
        component.setName(request.getName());
        return componentRepo.save(component);
    }

    @Override
    public ComponentStatus start(String componentId) {
        Component component = componentRepo.findById(componentId, Component.class);
        if (component == null) {
            throw new BizException("invalid component id");
        }
        long num = componentInstanceRepo.instanceNum(componentId);
        if (num > 0) {
            throw new BizException("already started");
        }
        ComponentInstance instance = new ComponentInstance();
        instance.setComponentId(componentId);
        instance.setStartedAt(new Date());
        instance.setStartedBy(AuthUtil.currentUser().getId());
        ComponentStatus status = new ComponentStatus();
        status.setComponentId(componentId);
        status.setStatus(ComponentStatusEnum.STARTING);
        status.setInstanceId(instance.getInstanceId());
        return status;
    }
}
